Oct 19, 2023by Benjamin Gallois

Open-Source PPG Heart Rate Monitoring: Empowering Users with Raw Data Access

Introduction

Continuous heart rate monitoring and heart rate variability are frequently integrated into wearable devices. However, comprehensive data analysis (and access to RAW data) is often restricted behind a subscription paywall, making it inaccessible to many users. In this article, we introduce an open-source HR tracking device that is affordable and straightforward to construct. This device enables continuous HR monitoring and grants users access to the raw data, empowering them for in-depth personal analysis.

Material

MAX30100 preparation

The MAX30100 can be easily interfaced with an Arduino, but there’s an essential consideration due to its dual supply voltage requirement: 1.8V for the IC and 3.3V for the RED and IR LEDs. Since Arduino typically operates at 5V logic levels, connecting the MAX30100 directly will not work, as the logic level is too low for the device, causing it to not function correctly on the I2C bus. One viable solution to this dilemma involves physically altering the circuit by cutting a trace and creating a new connection. For detailed instructions on achieving this, refer to this informative guide: https://lastminuteengineers.com/max30100-pulse-oximeter-heart-rate-sensor-arduino-tutorial/.

From https://lastminuteengineers.com/max30100-pulse-oximeter-heart-rate-sensor-arduino-tutorial/.
From https://lastminuteengineers.com/max30100-pulse-oximeter-heart-rate-sensor-arduino-tutorial/.

MAX30100 wiring

Connecting the MAX30100 to the Gemma M0 is a straightforward process, requiring only a few simple connections:

These connections enable proper communication and power supply between the MAX30100 and the Gemma M0.

The wired device has the MAX30100 on top and the Gemma on the bottom. It is isolated using electrical tape and held together with a Velcro strap.

Gemma

We will employ a simple Arduino sketch to obtain RAW data from the MAX30100 chip. Initially, we must configure the Gemma by utilizing the Adafruit library. For detailed setup instructions, refer to the document accessible at https://www.mouser.com/pdfdocs/adafruit-gemma-m0.pdf#__WKANCHOR_3k. Subsequently, we should install the MAX30100 library for Arduino within the Arduino IDE:

Finally, in the Arduino IDE, select the appropriate port, choose the correct board (Gemma M0), and set the USB Stack to “tinyUSB” before uploading the sketch to the Gemma.

    #include 	<Wire.h>
    #include "MAX30100_PulseOximeter.h"
    #include "Adafruit_TinyUSB.h"
    // Create a MAX30100 object
    MAX30100 sensor;
    void setup() {
    Serial.begin(115200);
    Serial.print("Initializing MAX30100..");
    // Initialize sensor
    if (!sensor.begin()) {
    Serial.println("FAILED");
    for(;;);
    } else {
    Serial.println("SUCCESS");
    }
    // Configure sensor
    configureMax30100();
    }
    void loop() {
    uint16_t ir, red;
    sensor.update();
    while (sensor.getRawValues(&ir, &red)) {
    Serial.print(red);
    Serial.print(", ");
    Serial.println(ir);
    }
    }
    void configureMax30100() {
    sensor.setMode(MAX30100_MODE_SPO2_HR);
    sensor.setLedsCurrent(MAX30100_LED_CURR_27_1MA, MAX30100_LED_CURR_27_1MA);
    sensor.setLedsPulseWidth(MAX30100_SPC_PW_1600US_16BITS);
    sensor.setSamplingRate(MAX30100_SAMPRATE_100HZ);
    sensor.setHighresModeEnabled(true);
    }
    

Software

Acquisition

With the hardware now correctly configured, the next step is to log the RAW data for subsequent processing. To achieve this, we will employ a straightforward Python program. This program will establish a serial connection with the Gemma, retrieve RAW data from the sensor, append a timestamp to the data, and then save it to a CSV file for further analysis and utilization.

import serial
import time

name = time.strftime("%Y%m%d-%H%M%S")
timeout = time.time() + 60*5

with serial.Serial('/dev/ttyACM0', 115200, timeout=None) as ser:
    with open(name + ".txt", "w") as f:
        while True:
            f.write(str(time.time_ns()) + ", " + str(ser.readline(), 'ISO-8859-1'))
    
Entire RAW signal.
Zoom RAW signal.

Analysis

The data analysis process will closely resemble what we’ve discussed in previous posts. It involves using Pandas and SciPy for data loading and cleaning of the time series, and the HrvAnalysis package for computing HRV features. The data analysis is straightforward:

Entire filtered data.
Zoom filtered data.
Peaks detection.

Testing

Data

To evaluate the performance of this open-source continuous monitor, we conducted a test by recording data from a subject’s entire night of sleep using the setup and analysis methodology detailed earlier. The recorded data is divided into intervals of 3 minutes, from which we extract HRV parameters.

The device is secured to the test subject’s finger, and the power and data cable can be looped around the thumb to prevent disconnection during sleep movement.

Result

Without delving too deeply into the intricacies of nocturnal data analysis, we observe that our recorded data aligns closely with previous recordings obtained, for instance, with devices like the Oura band. The trends show a decrease in heart rate (HR) and an increase in heart rate variability (HRV) indicators throughout the night, indicating a positive sign of recovery during sleep.

HRV metrics during one sleep night.

In the last minute of the recording, the following parameters were compared with measurements obtained using the smartphone application HRV4training:

Consideration

The PPG signal is recognized for its susceptibility to motion artifacts. In our dataset, it’s evident that motion triggers substantial mean shifts in the PPG signal, which can be rectified by applying pass-band filters. It’s imperative to conduct further tests to determine if other types of motion artifacts during sleep might affect the data. Remarkably, unnatural movements, such as periodic finger tapping, render the PPG signal less reliable. In upcoming posts, we will explore various motion artifacts and their impact on the data.

Conclusion

In this article, we introduced an open-source continuous heart rate monitoring device. We outlined the components and setup, including an Arduino sketch to collect raw data. The software section covered data acquisition and analysis. Testing showed promising results in line with commercial devices. We noted potential motion artifacts impacting data reliability, to be explored further. This affordable solution empowers users to monitor and analyze their heart rate data, democratizing access to valuable health insights.